package com.study.spmongodb.book.wwj.char26;

/**
 * @author MI
 * @version 1.0
 * @date 2020/12/3 20:53
 */
public class ProductionChannel {
    /**
     * 传送带上最多可以有多少个待加工的产品
     */
    private final static int MAX_PROD = 10;
    /**
     * 主要用来存放待加工的产品，也就是传送带
     */
    private final Production[] productionQueue;

    /**
     * 队列头
     */
    private int head;
    /**
     * 队列尾
     */
    private int tail;
    /**
     * 当前流水线上有多少个待加工的产品
     */
    private int total;

    /**
     * 在流水线上的 工人
     */
    private final Worker[] workers;

    public ProductionChannel(int workerSize) {
        this.workers = new Worker[MAX_PROD];
        this.productionQueue = new Production[MAX_PROD];

        //实例化每一个工人(Wokder线程)，并启动
        for (int i = 0; i < workerSize; i++) {
            workers[i] = new Worker("Worker-" + i, this);
            workers[i].start();
        }
    }

    /**
     * 接受来自上游的代加工产品
     *
     * @param production
     */
    public void offerProduction(Production production) {
        synchronized (this) {

            while (total >= productionQueue.length) {
                try {
                    this.wait();
                } catch (InterruptedException e) {

                }
            }
            //将产品放到传送带，并且通知工人线程工作
            productionQueue[tail] = production;
            tail = (tail + 1) % productionQueue.length;
            total++;
            this.notifyAll();
        }
    }

    public Production takeProduction() {
        synchronized (this) {
            //当传送带上没有产品时，工人等待 这产品从上游输送到传送带上。
            while (total <= 0) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            //获取产品
            final Production prod = productionQueue[head];
            head = (head + 1) % productionQueue.length;
            total--;
            this.notifyAll();
            return prod;
        }
    }


}
